/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package botsim;

import com.bulletphysics.collision.broadphase.AxisSweep3;
import com.bulletphysics.collision.dispatch.CollisionDispatcher;
import com.bulletphysics.collision.dispatch.DefaultCollisionConfiguration;
import com.bulletphysics.collision.shapes.BoxShape;
import com.bulletphysics.dynamics.DiscreteDynamicsWorld;
import com.bulletphysics.dynamics.DynamicsWorld;
import com.bulletphysics.dynamics.RigidBody;
import com.bulletphysics.dynamics.constraintsolver.SequentialImpulseConstraintSolver;
import com.bulletphysics.linearmath.DefaultMotionState;
import com.bulletphysics.linearmath.Transform;
import javax.vecmath.Vector3f;


/**
 *
 * @author Prasanna Velagapudi <pkv@cs.cmu.edu>
 */
public class BulletExample {
    public static void main(String[] args) {
        DynamicsWorld world = createWorld();

        RigidBody ground = createBox(0.0f, new Vector3f(10.0f, 0.001f, 10.0f), new Vector3f(0.0f, 0.0f, 0.0f));
        world.addRigidBody(ground);


        for (int i = 0; i < 1000; i++) {
            RigidBody box = createBox(1.0f, new Vector3f(0.5f, 0.5f, 0.5f), 
                    new Vector3f((float)Math.random()*10.0f, 20.0f + (float)i, (float)Math.random()*10.0f));
            world.addRigidBody(box);
        }

        ArdorWindow window = createWindow(world);
        window.run();
    }

    /**
     * Initialize boilerplace Bullet physics world
     * @return
     */
    public static DynamicsWorld createWorld() {
        // Build the broadphase
        int maxProxies = 1024;
        Vector3f worldAabbMin = new Vector3f(-10000,-10000,-10000);
        Vector3f worldAabbMax = new Vector3f(10000,10000,10000);
        AxisSweep3 broadphase = new AxisSweep3(worldAabbMin,worldAabbMax,maxProxies);

        // Set up the collision configuration and dispatcher
        DefaultCollisionConfiguration collisionConfiguration = new DefaultCollisionConfiguration();
        CollisionDispatcher dispatcher = new CollisionDispatcher(collisionConfiguration);

        // The actual physics solver
        SequentialImpulseConstraintSolver solver = new SequentialImpulseConstraintSolver();

        // The world.
        return new DiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
    }

    public static RigidBody createBox(float mass, Vector3f extents, Vector3f position) {
        Transform xform = new Transform();
        xform.setIdentity();
        xform.origin.set(position);
        return new RigidBody(mass, new DefaultMotionState(xform), new BoxShape(extents));
    }

    public static ArdorWindow createWindow(final DynamicsWorld world) {
        // Create a new BulletScene containing bullet debug world
        BulletScene BulletScene = new BulletScene(world);

        // Create simple viewer window to show world
        return new ArdorWindow(ArdorWindow.LWJGL_RENDERER, BulletScene);
    }
}
